package org.sfans.common.utils;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.digest.DigestUtils;

/**
 * 对web操作常用工具类
 * @author L.cm
 * @email: 596392912@qq.com
 * @site: http://www.dreamlu.net
 * @date 2015年4月19日下午2:15:31
 */
public final class WebUtils {

	private WebUtils() {}

	/**
	 * 密码hex，先sha1然后md5
	 * @param pwd
	 * @return
	 */
	public static String encodePwd(String password) {
		return DigestUtils.md5Hex(DigestUtils.sha1Hex(password));
	}

	/**
	 * 静态内部类，定义用户状态维持cookie
	 * cookie设计为: des(私钥).encode(uuid~nickName~time~maxAge~ip)
	 */
	public static class UserCookie {
		// cookie保存的key
		private static final String COOKIE_USER_KEY = "u_id";

		// 用户的唯一id *（需要加密）
		private final String id;
		// 用户的昵称
		private final String nickName;

		public UserCookie(String id, String nickName) {
			super();
			this.id = id;
			this.nickName = nickName;
		}

		public String getId() {
			return id;
		}

		public String getNickName() {
			return nickName;
		}

	}

	/**
	 * 返回前台、Wap当前用户
	 * @param HttpServletRequest
	 * @param HttpServletResponse
	 * @return UserCookie
	 */
	public static UserCookie currentUser(HttpServletRequest request, HttpServletResponse response) {
		String userCookie = getCookie(request, UserCookie.COOKIE_USER_KEY);
		// 1.cookie为空，直接清除
		if (!StringUtils.hasText(userCookie)) {
			removeCookie(response, UserCookie.COOKIE_USER_KEY);
			return null;
		}
		// 2.解密cookie
		String cookieInfo = null;
		try {
			cookieInfo = new DESUtils().decryptString(userCookie);
		} catch (RuntimeException e) {
			// ignore
		}
		// 3.异常或解密问题，直接清除cookie信息
		if (!StringUtils.hasText(cookieInfo)) {
			removeCookie(response, UserCookie.COOKIE_USER_KEY);
			return null;
		}
		String[] userInfo = cookieInfo.split("~");
		// 4.规则不匹配，昵称中含有`~`??
		if (userInfo.length < 4) {
			removeCookie(response, UserCookie.COOKIE_USER_KEY);
			return null;
		}
		String id       = userInfo[0];
		String nickName = userInfo[1];
		String oldTime  = userInfo[2];
		String maxAge   = userInfo[3];
		// 5.判定时间区间，超时的cookie清理掉
		if (!"-1".equals(maxAge)) {
			long now  = System.currentTimeMillis();
			long time = Long.parseLong(oldTime) + (Long.parseLong(maxAge) * 1000);
			if (time <= now) {
				removeCookie(response, UserCookie.COOKIE_USER_KEY);
				return null;
			}
		}
		return new UserCookie(id, nickName);
	}

	/**
	 * 用户登陆状态维持
	 * 
	 * cookie设计为: des(私钥).encode(uuid~nickName~time~maxAge~ip)
	 * 
	 * @param Controller 控制器
	 * @param UserModel  用户model
	 * @param remember   是否记住密码、此参数控制cookie的 maxAge，默认为-1（只在当前会话）<br>
	 *                   记住密码默认为一周
	 * @return void
	 */
	public static void loginUser(HttpServletRequest request, HttpServletResponse response, long usersId, boolean... remember) {
		// 获取用户的id、nickName
		// 当前毫秒数
		long   now      = System.currentTimeMillis();
		// 超时时间
		int    maxAge   = -1;
		if (remember.length > 0 && remember[0]) {
			maxAge      = 60 * 60 * 24 * 7;
		}
		// 用户id地址
		String ip		= getIP(request);
		// 构造cookie
		StringBuilder cookieBuilder = new StringBuilder()
			.append(usersId).append("~")
			.append(now).append("~")
			.append(maxAge).append("~")
			.append(ip);
		// 加密cookie
		String userCookie = new DESUtils().encryptString(cookieBuilder.toString());
		// 设置用户的cookie、 -1 维持成session的状态
		setCookie(response, UserCookie.COOKIE_USER_KEY, userCookie, maxAge);
	}

	/**
	 * 读取cookie
	 * @param request
	 * @param key
	 * @return
	 */
	public static String getCookie(HttpServletRequest request, String key) {
		Cookie[] cookies = request.getCookies();
		if(null != cookies){
			for (Cookie cookie : cookies) {
				if (key.equals(cookie.getName())) {
					return cookie.getValue();
				}
			}
		}
		return null;
	}

	/**
	 * 清除 某个指定的cookie 
	 * @param response
	 * @param key
	 */
	public static void removeCookie(HttpServletResponse response, String key) {
		setCookie(response, key, null, 0);
	}

	/**
	 * 设置cookie
	 * @param response
	 * @param name
	 * @param value
	 * @param maxAgeInSeconds
	 */
	public static void setCookie(HttpServletResponse response, String name, String value, int maxAgeInSeconds) {
		Cookie cookie = new Cookie(name, value);
		cookie.setPath("/");
		cookie.setMaxAge(maxAgeInSeconds);
		cookie.setHttpOnly(true);
		response.addCookie(cookie);
	}

	/**
	 * 获取ip
	 * @param request
	 * @return
	 */
	public static String getIP(HttpServletRequest request) {
		String ip = request.getHeader("X-Requested-For");
		if (StringUtils.isNotBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("X-Forwarded-For");
		}
		if (StringUtils.isNotBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (StringUtils.isNotBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (StringUtils.isNotBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_CLIENT_IP");
		}
		if (StringUtils.isNotBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_X_FORWARDED_FOR");
		}
		if (StringUtils.isNotBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		return ip;
	}
}
